<?php

namespace App\Library\FeiShu;

use App\Exceptions\BaseException;
use App\Kuafu\Base\Enum\BaseCodeEnum;

class SendFs
{
    private $openUrl; // 机器人通知地址
    private $rootSecret; // 签名字符

    private string $title;
    private array  $fsContent = [];

    public const ROBOT_WARNING                 = 'FS'; // 报警
    public const ROBOT_RJD                     = 'FS_RJD'; // 日结单
    public const ROBOT_GUANYUAN                = 'FS_GUANYUAN'; // 给观远推数 通知
    public const ROBOT_AUDIT                   = 'FS_AUDIT'; // 审计
    public const ROBOT_CHECK                   = 'FS_CHECK'; // 对账
    public const ROBOT_INTERNAL                = "FS_INTERNAL"; // 内部
    public const ROBOT_BUSINESS_WARING         = "FS_BUSINESS_WARING"; // 业务报警机器人
    public const ROBOT_STATISTICAL             = "FS_STATISTICAL"; // 统计机器人
    public const ROBOT_APPLET_COMPLAIN         = "FS_APPLET_COMPLAIN"; // 小程序-投诉
    public const ROBOT_ALI_WORK_SYNC           = "FS_ALI_WORK_SYNC"; // 宜搭机器人配置-对外
    public const ROBOT_BATCH_BILL_MATCH        = "FS_BATCH_BILL_MATCH"; // 外卖平台与网商账单匹配机器人
    public const ROBOT_POS_MQTT_STATUS         = "FS_POS_MQTT_STATUS";// MQTT 状态机器人
    public const ROBOT_POS_MISS_EXT_PRODUCT    = "FS_POS_MISS_EXT_PRODUCT";// 抖音三方商品缺失就机器人
    public const ROBOT_POS_MISS_MT_EXT_PRODUCT = "FS_POS_MISS_MT_EXT_PRODUCT";// 美团三方商品缺失就机器人
    public const ROBOT_SHOP_CAMERA_DATA_STATUS = "FS_SHOP_CAMERA_DATA_STATUS";// 门店客流数据机器人
    public const ROBOT_FS_API_TIME             = "FS_API_TIME"; // API-TIME
    public const ROBOT_FS_BUSINESS_ERROR       = "FS_BUSINESS_ERROR"; // 业务报错推送机器人
    public const ROBOT_FS_MY_BANK              = "FS_MY_BANK"; // 网商报错业务推送
    public const ROBOT_MY_BANK_DEL             = "FS_MY_BANK_DEL"; // 网商删除账号
    public const ROBOT_FS_POS_DOU_YIN_NOTIFY   = "FS_POS_DOU_YIN_NOTIFY"; // pos收银抖音通知异常
    public const ROBOT_FS_YW_MONITOR           = "FS_YW_MONITOR"; // 运维群监控
    public const ROBOT_FS_APP_USER_DATA        = "FS_APP_USER_DATA"; // app用户数据
    public const ROBOT_MAP_KEY_LOSE_EFFECTIVE  = "FS_MAP_KEY_LOSE_EFFECTIVE"; // 地图key失效

    private function __construct($robot)
    {
        $this->openUrl    = config('other.' . $robot . '_HOCK_URL', 'other.FS_HOCK_URL');
        $this->rootSecret = config('other.' . $robot . '_SECRET_TOKEN', 'other.FS_SECRET_TOKEN');
    }

    public static function newRobot($robot = self::ROBOT_WARNING): SendFs
    {
        return new static($robot);
    }

    /**
     * 强制设置机器人配置
     * @param string $openUrl
     * @param string $rootSecret
     * @return $this
     */
    public function forceSetRobot(string $openUrl, string $rootSecret): self
    {
        $this->openUrl    = $openUrl;
        $this->rootSecret = $rootSecret;

        return $this;
    }

    /**
     * 设置标题内容
     * @param string $title
     * @param string $content
     * @return $this
     */
    public function setTitleContent(string $title, string $content, string $atUid = '', bool $withPrefix = true): self
    {
        $this->title = ($withPrefix ? "通知-" . config('app.env') . "：{$title}" : $title);

        if ($content) {
            $this->fsContent[] = ['tag' => 'text', 'text' => $content];
        }

        if ($atUid) {
            $this->fsContent[] = ['tag' => 'at', 'user_id' => $atUid];
        }

        return $this;
    }

    public function setAtUid(string $atUid): self
    {
        $this->fsContent[] = ['tag' => 'at', 'user_id' => $atUid];

        return $this;
    }

    public function setAtUids(array $atUids): self
    {
        foreach ($atUids as $atUid) {
            $this->fsContent[] = ['tag' => 'at', 'user_id' => $atUid];
        }
        return $this;
    }

    public function setUrl(string $text, string $url, int $line = 0)
    {
        if ($line == 1) {
            $this->fsContent[] = ['tag' => 'text', 'text' => "\n"];
        }
        $this->fsContent[] = [
            'tag'  => 'a',
            'text' => $text,
            'href' => $url,
        ];
        return $this;
    }

    /**
     * HmacSHA256 算法计算签名
     * @param $time
     * @return string
     */
    private function makeSign($time)
    {
        $string = "{$time}\n{$this->rootSecret}";
        return base64_encode(hash_hmac('sha256', "", $string, true));
    }

    /**
     * 发送请求
     * @return mixed
     */
    public function send()
    {
        $timestamp = time();
        $data      = json_encode([
            'timestamp' => $timestamp,
            'sign'      => $this->makeSign($timestamp),
            'msg_type'  => 'post',
            'content'   => [
                'post' => [
                    'zh_cn' => [
                        'title'   => $this->title,
                        'content' => [
                            $this->fsContent,
                        ]
                    ]
                ]
            ],
        ], JSON_UNESCAPED_UNICODE);

        $curlObj = curl_init();
        $ssl     = stripos($this->openUrl, 'https://') === 0 ? true : false;
        $options = [
            CURLOPT_URL            => $this->openUrl,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_POST           => 1,
            CURLOPT_POSTFIELDS     => $data,
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_AUTOREFERER    => 1,
            CURLOPT_USERAGENT      => 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)',
            CURLOPT_TIMEOUT        => 1, // 1秒超时
            CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_0,
            CURLOPT_HTTPHEADER     => ['Expect:'],
            CURLOPT_IPRESOLVE      => CURL_IPRESOLVE_V4,
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
        ];

        if ($ssl) {
            //support https
            $options[CURLOPT_SSL_VERIFYHOST] = false;
            $options[CURLOPT_SSL_VERIFYPEER] = false;
        }
        curl_setopt_array($curlObj, $options);
        $returnData = curl_exec($curlObj);
        if (curl_errno($curlObj)) {
            //error message
            $returnData = curl_error($curlObj);
        }
        curl_close($curlObj);
        return $returnData;
    }

    /**
     * @所有人
     * @return $this
     */
    public function setAtAll(): self
    {
        $this->fsContent[] = ['tag' => 'at', 'user_id' => 'all'];

        return $this;
    }


    public function getOpenUrl()
    {
        return $this->openUrl;
    }

    public function getRootSecret()
    {
        return $this->rootSecret;
    }

}
